/*--------------------------------------------------------------------------------------------------
Yatak Operation System Project Copyright 2012
Author : Ilya Churaev
Started : 23 Apr 2012	Updated : 5 Oct 2012
File Name : shell.c     Purpose : main terminal
--------------------------------------------------------------------------------------------------*/
#include <yatak/version.h>
#include <yatak/kheap.h>
#include <keyboard.h>
#include <screen.h>
#include <shell.h>
#include <users.h>
#include <timer.h>
#include <time.h>
#include <log.h>

shell_var_t * variables = NULL;
static int count_copy = 0;

static char currentdir [256] = "/";
static fs_node_t *fsnode = NULL;

void print_user_str ()
{
	if (whoami())
		kprintf ("%s:",whoami ());
	kprintf("%s",currentdir);
	if (!strcmp (whoami (),"root"))
		kprintf ("#");
	else
		kprintf (">");
}

int GetNumCopy ()
{
	return count_copy;
}

fs_node_t * GetRootFS ()
{
	return fs_root;
}

fs_node_t * GetCurrentNodeDir ()
{
	return fsnode;
}

void SetCurrentNodeDir (fs_node_t * dir)
{
	fsnode = dir;
}

char * GetCurrentDir ()
{
	return currentdir;
}

void SetCurrentDir (char * dir)
{
	strcpy (currentdir, dir);
}

int CreateVariable (char * name, void * value,uint32 size)
{
	if (!name)
	{
		dprintf ("[CreateVariable] name = NULL...\n");
		return 1;
	}
	if (!variables)
	{
		variables = (shell_var_t *)kmalloc (sizeof (shell_var_t));
		variables->size = size;
		variables->value = (void *)kmalloc (size);
		memcpy (variables->value, value, size);
		strcpy (variables->name, name);
		variables->next = NULL;
		variables->back = NULL;
		return 0;
	}
	shell_var_t * tmp = variables;
	
	while (tmp->next) tmp = tmp->next;
	
	tmp->next = (shell_var_t *)kmalloc (sizeof (shell_var_t));
	tmp->next->back = tmp;
	tmp = tmp->next;
	tmp->next = NULL;
	tmp->size = size;
	tmp->value = (void *)kmalloc (size);
	memcpy (tmp->value, value, size);
	strcpy (tmp->name, name);
	return 0;
}

int DeleteVariable (char * name)
{
	if (!name)
	{
		dprintf ("[DeleteVariable] name = NULL...\n");
		return 1;
	}
	if (!variables)
	{
		dprintf ("[DeleteVariable] variables = NULL...\n");
		return 2;
	}
	
	shell_var_t * tmp = variables;
	while (tmp->next)
	{
		if (!strcmp (tmp->name,name))
			break;
		tmp = tmp->next;
	}
	if (strcmp (tmp->name,name))
	{
		dprintf ("[DeleteVariable] Cannot find variable...\n");
		return 3;
	}
	if (tmp == variables)
		variables = tmp->next;
	if (tmp->back)
		tmp->back->next = tmp->next;
	if (tmp->next)
		tmp->next->back = tmp->back;
	kfree (tmp->value);
	kfree (tmp);
	return 0;
}

void * GetVariable (char * name)
{
	if (!name)
	{
		dprintf ("[GetVariable] name = NULL...\n");
		return 1;
	}
	if (!variables)
	{
		dprintf ("[GetVariable] variables = NULL...\n");
		return 2;
	}
	
	shell_var_t * tmp = variables;
	while (tmp->next)
	{
		if (!strcmp (tmp->name,name))
			break;
		tmp = tmp->next;
	}
	if (strcmp (tmp->name,name))
	{
		dprintf ("[GetVariable] Cannot find variable...\n");
		return 3;
	}
	return tmp->value;
}

uint32 GetVariableSize (char * name)
{
	if (!name)
	{
		dprintf ("[GetVariable] name = NULL...\n");
		return 1;
	}
	if (!variables)
	{
		dprintf ("[GetVariable] variables = NULL...\n");
		return 2;
	}
	
	shell_var_t * tmp = variables;
	while (tmp->next)
	{
		if (!strcmp (tmp->name,name))
			break;
		tmp = tmp->next;
	}
	if (strcmp (tmp->name,name))
	{
		dprintf ("[GetVariable] Cannot find variable...\n");
		return 3;
	}
	return tmp->size;
}

static void DeleteVariables ()
{
	while (variables) DeleteVariable(variables->name);
}

void DrawShell ();

void start_shell ()
{
	char * str = kmalloc (sizeof (char)*1024);
	DrawShell ();
	if (!fsnode)
		fsnode = fs_root;
	count_copy++;
	ShowTime (true);
	for (;;)
	{
		in_string (str, 1024);
		write_log("History",str,strlen(str));
		if (command_line(str))
			break;
		print_user_str ();
	}
	kfree (str);
	DeleteVariables ();
	--count_copy;
}

void DrawShell ()
{
	if (!count_copy)
	{
		cls ();
#ifdef END_YEAR
		kprintf ("Yatak Shell. Version 0.2. %s %s-%s by %s.\n", COPYRIGTH, START_YEAR, END_YEAR, AUTHOR);
#else
		kprintf ("Yatak Shell. Version 0.2. %s %s by %s.\n", COPYRIGTH, START_YEAR, AUTHOR);
#endif
		print_user_str ();
	}
	return;
}
